import { observable, action } from "mobx";
// import $ from "jquery";

export default class MindMapStore {
    @observable rootDatas: any ={};
    nodes:any;  //所有的节点
    links:any;  //所有的连线
    gNode:any;  //所有节点组
    gLink:any;  //所有连线组
    root:any;

    width =window.document.body.offsetWidth-4;
    height =window.document.body.offsetHeight-4;
    isFirstInit=true;  //是否第一次渲染图形

    @action
    init=()=>{

        const d3: any = window['d3'];

        //基础数据处理
        this.rootDatas={
            "name": "Ev22222222222e",
            "children": [
                {
                    "name": "Cain"
                },
                {
                    "name": "Seth",
                    "children": [
                        {
                            "name": "Enos",
                            "children":[{name:'zneghao'}]
                        },
                        {
                            "name": "Noam"
                        }
                    ]
                },
                {
                    "name": "Abel"
                },
                {
                    "name": "Awan",
                    "children": [
                        {
                            "name": "Enoch"
                        }
                    ]
                },
                {
                    "name": "Azura"
                }
            ]
        };
        this.root = d3.hierarchy(this.rootDatas);
        this.root.descendants().forEach((d, i) => {
            d.id = i;
            d._children = d.children;
        });
        this.root.x0 = 50;
        this.root.y0 = 0;

        const mindMapContainer=d3.select('#mindMapContainer').attr('width',this.width).attr('height',this.height).attr('transform',d3.zoomIdentity).append("g");
        this.gNode = mindMapContainer.append("g").attr('id','nodeGroup');
        this.gLink=mindMapContainer.append('g').attr('id','nodePath');
        this.isFirstInit=true;
        this.updateNode(this.root);
        d3.select('#mindMapContainer').call(d3.zoom().scaleExtent([1/10, 10]).on("zoom", ()=>{mindMapContainer.attr("transform", d3.event.transform.toString());}));
        window.focus(); 
    }

    @action
    updateNode=(sourceNode)=>{
        const d3: any = window['d3'];
        this.nodes = this.root.descendants();
        this.links = this.root.links();
        const tree=d3.tree().nodeSize([50, 100]);
        tree(this.root);//计算x及y赋予this.root

        let left = this.root;
        let right = this.root;
        this.root.eachBefore(node => {//感觉y是屏幕上的横坐标，x是纵坐标
            if (node.y < left.y) left = node;
            if (node.y > right.y) right = node;
        });
        //动画效果
        const transition = d3.select('#mindMapContainer').transition().duration(500);
        if(this.isFirstInit){
            d3.select('#mindMapContainer').attr("viewBox",(-(this.width-(right.y-left.y))/2)+","+(-this.height/2)+","+this.width+","+this.height);
        }
        //节点处理
        const node=this.gNode.selectAll("g").data(this.nodes,d=>d.id);
        const nodeEnter = node.enter().append('g').attr("transform", d => `translate(${sourceNode.y0},${sourceNode.x0})`).on("click", d => {
            d.children = d.children ? null : d._children;
            this.updateNode(d);
        });
        nodeEnter.append('circle').attr('r',15).attr('fill',d=>d._children?'#555':'#999');
        nodeEnter.append("text").attr("dy", "0.31em").attr("x", d => d._children ? -6 : 6).attr("text-anchor", d => d._children ? "end" : "start").text(d => d.data.name);
        node.merge(nodeEnter).transition(transition).attr("transform", d =>`translate(${d.y},${d.x})`).attr("fill-opacity", 1).attr("stroke-opacity", 1);
        node.exit().transition(transition).remove().attr("transform", d => `translate(${sourceNode.y},${sourceNode.x})`).attr("fill-opacity", 0).attr("stroke-opacity", 0);
        //连线处理
        this.gLink.attr("fill", "none").attr("stroke", "#555").attr("stroke-opacity", 0.4).attr("stroke-width", 1.5);
        const link = this.gLink.selectAll("path").data(this.links,d =>d.target.id);
        const diagonal = d3.linkHorizontal().x(d => d.y).y(d => d.x);
        const linkEnter=link.enter().append('path').attr('d',d=>{
            const o = {x: sourceNode.x0, y: sourceNode.y0};
            return diagonal({source: o, target: o});
        });
        link.merge(linkEnter).transition(transition).attr("d", diagonal);
        link.exit().transition(transition).remove().attr("d", d => {
            const o = {x: sourceNode.x, y: sourceNode.y};
            return diagonal({source: o, target: o});
        });

        // Stash the old positions for transition.
        this.root.eachBefore(d => {
            d.x0 = d.x;
            d.y0 = d.y;
        });
        this.isFirstInit=false;
    }


}